#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<cerrno>
#include<memory>
#include<strings.h>

#include<sys/types.h>
#include<sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include"Log.hpp"
#include "Common.hpp"
#include"InetAddr.hpp"

using namespace LogModule;

int main(int argc ,char* argv[])
{
    if(argc != 3)
    {
        std::cout <<"Usage: "<<argv[0]<<"serverip serverport"<<std::endl;
        Die(USAGE_ERR);
    }

    std::string ip = argv[1];
    uint16_t port = std::stoi(argv[2]);

    //1.创建套接字
    int sockfd = ::socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd < 0)
    {
        LOG(LogLevel::FATAL)<<"socket : "<<strerror(errno);
        Die(SOCKET_ERR);
    }

    // //2.填充服务器网络信息
    // struct sockaddr_in server;
    // memset(&server,0,sizeof(server));
    // server.sin_family = AF_INET;
    // server.sin_addr.s_addr = ::inet_addr(ip.c_str());
    // server.sin_port = ::htons(port); 
    InetAddr server(port);

    //向服务器发送消息
    while(true)
    {
        std::cout <<"Please Enter#";
        std::string message;
        std::getline(std::cin,message);

        //发消息，客户端不需要显示绑定，端口号在第一次向服务器发送消息时，由内核随机发放，保证唯一性
        ssize_t n = ::sendto(sockfd,message.c_str(),sizeof(message),0,server.NetAddr(),server.NetAddrLen());
        (void)n;

        //接受服务器的消息
        struct sockaddr_in temp;
        socklen_t len = sizeof(temp);
        char buffer[1024];
        n = recvfrom(sockfd,buffer,sizeof(buffer),0,CONV(&temp),&len);
        if(n > 0)
        {
            buffer[n] = 0;
            std::cout << buffer<<std::endl;
        }
    }

    return 0;
}